/*
 * app_keyScan.h
 *
 *  Created on: 2023年8月30日
 *      Author: zlw
 */

#ifndef DS_APP_INS_APP_KEYSCAN_H_
#define DS_APP_INS_APP_KEYSCAN_H_

#include "stdbool.h"
#include "bsp_keyscan.h"
#include "em_cmu.h"
#include "em_gpio.h"

#define VALUE_COUNT_MAX (32)

#define LONG_PRESS_TIMEOUT     (27)
#define SHORT_PRESS_TIMEOUT    (7)

typedef struct {
  uint8_t valueCnt;
  uint8_t stopBit;
  uint8_t value[VALUE_COUNT_MAX];
}keyPadValue_t;

typedef void (*keyCallBack)(void*);

typedef enum {
  KEY_DOWN,
  KEY_LONG,
  KEY_CLICK,
  NONE_EVENT
}keyEvent_t;

typedef struct{
  keyEvent_t event;
  uint8_t keyValue;
  uint16_t ticks;
  keyCallBack cb[NONE_EVENT-1];
}keyIns_t;

#define KEYSCAN_DRIVER_EVENT_WAKEUP  (0x01)
#define KEYSCAN_DRIVER_EVENT_SCANNED (0x02)
#define KEYSCAN_DRIVER_EVENT_KEY     (0x04)
#define KEYSCAN_DRIVER_EVENT_NOKEY   (0x08)

#define KEYSCAN_DRIVER_COLUMN_NUMBER 5
#define KEYSCAN_DRIVER_ROW_NUMBER    3


#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_0_PORT gpioPortC
#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_0_PIN  2

#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_1_PORT gpioPortC
#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_1_PIN  3

#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_2_PORT gpioPortC
#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_2_PIN  4

#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_3_PORT gpioPortC
#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_3_PIN  5

#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_4_PORT gpioPortC
#define KEYSCAN_DRIVER_KEYSCAN_COL_OUT_4_PIN  1

#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_0_PORT gpioPortA
#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_0_PIN 0

#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_1_PORT gpioPortA
#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_1_PIN 6

#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_2_PORT gpioPortA
#define KEYSCAN_DRIVER_KEYSCAN_ROW_SENSE_2_PIN 7

#define KEYSCAN_DRIVER_SCAN_DELAY_MS    SL_KEYSCAN_DELAY_10MS
#define KEYSCAN_DRIVER_DEBOUNCE_DELAY_MS    SL_KEYSCAN_DELAY_30MS
#define KEYSCAN_DRIVER_STABLE_DELAY_MS    SL_KEYSCAN_DELAY_10MS

#define KEYSCAN_DRIVER_SINGLEPRESS  0


void keyscan_driver_init(void);

bool key_scan_sleep_state_get(void);
void key_scan_sleep_state_set(bool state);
bool key_pad_wake_up_by_mistake_state_get(void);
void key_value_buffer_clear(void);
bool key_value_buffer_get(keyPadValue_t *padValue);

/***************************************************************************//**
 * Gets the info on auto-start feature enable status.
 *
 * @return  true, if auto-start feature is enabled.
 *          false, otherwise.
 ******************************************************************************/
__STATIC_INLINE bool keyscan_driver_hal_is_autostart_enabled(void)
{
  return (KEYSCAN->CFG & _KEYSCAN_CFG_AUTOSTART_MASK) ? true : false;
}

/***************************************************************************//**
 * Gets the info on single-press feature enable status.
 *
 * @return  true, if single-press feature is enabled.
 *          false, if multi-press feature is enabled instead.
 ******************************************************************************/
__STATIC_INLINE bool keyscan_driver_hal_is_singlepress_enabled(void)
{
  return (KEYSCAN->CFG & _KEYSCAN_CFG_SINGLEPRESS_MASK) ? true : false;
}

#endif /* DS_APP_INS_APP_KEYSCAN_H_ */
